package com.lagou.client;

import com.lagou.constant.Constant;
import com.lagou.model.Question;
import com.lagou.model.User;
import com.lagou.model.UserMessage;

import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import static com.lagou.constant.Constant.showResult;

/**

 * TODO: 编程实现管理员系统界面绘制和相应功能的实现

 */
public class ClientUserView {
    /**
     * 使用合成复用原则
     */
    private final ClientInitClose cic;
    /**
     * 登陆中的学员账户用户名
     */
    private String userName;

    /**
     * 通过构造方法实现成员变量的初始化
     *
     * @param cic 客户端初始化管理类的实例
     */
    public ClientUserView(ClientInitClose cic) {
        this.cic = cic;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    /**
     * 自定义成员方法实现管理员系统主界面的绘制
     *
     * @throws IOException            IO异常
     * @throws ClassNotFoundException 类型找不到异常
     */
    public void clientMainPage() throws IOException, ClassNotFoundException, InterruptedException {
        while (true) {
            System.out.println("\n\n\t    欢迎进入学员系统");
            System.out.println("------------------------------------");
            System.out.print("   [1] 用户模块");
            System.out.println("     [2] 考试模块");
            System.out.println("   [0] 退出系统");
            System.out.println("------------------------------------");
            System.out.println("请输入要进入的模块界面编号：");
            int choose = ClientScanner.getScanner().nextInt();
            switch (choose) {
                case 1:
                    System.out.println("正在进入用户模块界面...");
                    clientUserModulePage();
                    break;
                case 2:
                    System.out.println("正在进入考试模块界面...");
                    clientExamModulePage();
                    break;
                case 0:
                    System.out.println("正在退出系统...");
                    return;
                default:
                    System.out.println("输入错误，请重新选择！");
            }
        }
    }

    /**
     * 自定义成员方法实现学员管理界面的绘制
     *
     * @throws IOException            IO异常
     * @throws ClassNotFoundException 类型找不到异常
     */
    private void clientUserModulePage() throws IOException, ClassNotFoundException {
        while (true) {
            System.out.println("\n\n\t    欢迎进入用户模块");
            System.out.println("------------------------------------");
            System.out.print("   [1] 修改密码");
            System.out.println("     [0] 退出系统");
            System.out.println("------------------------------------");
            System.out.println("请输入要进行的操作编号：");
            int choose = ClientScanner.getScanner().nextInt();
            switch (choose) {
                case 1:
                    boolean changePass = clientChangePass();
                    if (changePass) {
                        return;
                    }
                    break;
                case 0:
                    System.out.println("正在退出系统...");
                    return;
                default:
                    System.out.println("输入错误，请重新选择！");
            }
        }
    }

    /**
     * 自定义成员方法实现客户端修改学员账户功能
     *
     * @throws IOException            IO异常
     * @throws ClassNotFoundException 类型找不到异常
     */
    private boolean clientChangePass() throws IOException, ClassNotFoundException {
        System.out.println("请输入修改后的新账户密码：");
        String password = ClientScanner.getScanner().next();
        // 封装消息并使用对象输出流发送给服务器
        UserMessage tum = new UserMessage(Constant.CHANGE_PASS, new User(userName, password));
        cic.getOos().writeObject(tum);
        System.out.println("客户端发送修改后的新账户密码！");
        // 接收服务器的处理结果并给出提示
        tum = (UserMessage) cic.getOis().readObject();
        showResult(tum, "修改账户密码成功！", "修改失败，没有该学员账户信息！");
        return Constant.SUCCESS.equals(tum.getType());
    }

    private void clientExamModulePage() throws IOException, ClassNotFoundException, InterruptedException {
        while (true) {
            System.out.println("\n\n\t    欢迎进入考试模块");
            System.out.println("------------------------------------");
            System.out.print("   [1] 开始考试");
            System.out.println("     [2] 导出成绩");
            System.out.print("   [3] 查询成绩");
            System.out.println("     [0] 退出系统");
            System.out.println("------------------------------------");
            System.out.println("请输入要进行的操作编号：");
            int choose = ClientScanner.getScanner().nextInt();
            switch (choose) {
                case 1:
                    clientStartExam();
                    break;
                case 2:
                    clientExportStore();
                    break;
                case 3:
                    clientGetStore();
                    break;
                case 0:
                    System.out.println("正在退出系统...");
                    return;
                default:
                    System.out.println("输入错误，请重新选择！");
            }
        }
    }

    /**
     * 自定义成员方法实现客户端导出成绩的功能
     */
    private void clientExportStore() throws IOException, ClassNotFoundException {
        // 封装消息并使用对象输出流发送给服务器
        UserMessage tum = new UserMessage(Constant.EXPORT_STORE, new User(userName));
        cic.getOos().writeObject(tum);
        // 接收服务器的处理结果并给出提示
        tum = (UserMessage) cic.getOis().readObject();
        showResult(tum, "导出成功！", "导出失败，该用户不存在！");
        if (Constant.SUCCESS.equals(tum.getType())) {
            writeStore(tum.getStoreData());
        }
    }

    /**
     * 自定义成员方法实现将成绩数据写入到要导出的文件中
     *
     * @param storeData 成绩数据
     */
    private void writeStore(char[] storeData) {
        FileWriter fw = null;
        try {
            // 1.构造FileWrite类型的对象与d:/store.txt文件关联
            // 若文件不存在，该流会自动创建新的空文件
            // 若文件存在，该流会清空文件中的原有内容
            fw = new FileWriter("d:/store.txt");

            // 将整个字符数组写进去
            fw.write(storeData);

            // 刷新流
            fw.flush();
            System.out.println("导出成绩成功！成绩文件：d:/store.txt");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 3.关闭流对象并释放有关的资源
            if (null != fw) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 自定义成员方法实现客户端查询成绩的功能
     */
    private void clientGetStore() throws IOException, ClassNotFoundException {
        // 封装消息并使用对象输出流发送给服务器
        UserMessage tum = new UserMessage(Constant.GET_STORE, new User(userName));
        cic.getOos().writeObject(tum);
        // 接收服务器的处理结果并给出提示
        tum = (UserMessage) cic.getOis().readObject();
        showResult(tum, "您的历史成绩如下：", "查询失败，该用户不存在！");
        if (Constant.SUCCESS.equals(tum.getType())) {
            for (int i = 0; i < tum.getUser().getStoreList().size(); i++) {
                System.out.println("第" + (i + 1) + "次考试，" + tum.getUser().getStoreList().get(i).show());
            }
        }
    }

    /**
     * 自定义成员方法实现导入考题的功能
     *
     * @throws IOException            IO异常
     * @throws ClassNotFoundException 类型找不到异常
     */
    private void clientStartExam() throws IOException, ClassNotFoundException, InterruptedException {
        System.out.println("开始抽题，请准备进入考试...");
        // 封装消息并使用对象输出流发送给服务器
        UserMessage tum = new UserMessage(Constant.START_EXAM);
        cic.getOos().writeObject(tum);
        // 接收服务器的处理结果并给出提示
        tum = (UserMessage) cic.getOis().readObject();
        Thread.sleep(5000);
        showResult(tum, "考试开始！", "抽题失败，系统出错，请重试！");
        if (Constant.SUCCESS.equals(tum.getType())) {
            exam(tum);
            // 接收服务器返回的成绩等信息
            tum = (UserMessage) cic.getOis().readObject();
            showResult(tum, "考试结束！", "请求出错，服务器没有收到你的作答！");
            if (Constant.SUCCESS.equals(tum.getType())) {
                System.out.println("本次考试的成绩为：" + tum.getUser().getStore().show());
            }
        }
    }

    private void exam(UserMessage tum) throws IOException {
        // 接收每次输入的选择
        String answer;
        // 存储所有的选择
        List<String> answerList = new LinkedList<>();
        List<Question> testPaper = tum.getTestPaper();
        for (int i = 0; i < testPaper.size(); i++) {
            System.out.println("第" + (i + 1) + "题：");
            System.out.println(testPaper.get(i).show());
            System.out.println("请输入你的答案（如：A）：");
            answer = ClientScanner.getScanner().next();
            answerList.add(answer);
        }
        tum.setType(Constant.END_EXAM);
        tum.setAnswerList(answerList);
        tum.setUser(new User(userName));
        cic.getOos().writeObject(tum);
    }
}
